/**
 * Project Name:nplus1
 * File Name:AvoidDuplicateSubmissionInterceptor.java
 * Package Name:com.gamma.nplus1.modules.sys.interceptor
 * Date:2016年2月29日下午5:17:33
 * Copyright (c) 2016, nplus1 Co., Ltd. All Rights Reserved.
 *
*/
package com.gamma.nplus1.modules.sys.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.gamma.nplus1.common.annotation.AvoidDuplicateSubmission;
import com.gamma.nplus1.common.exception.InvalidTokenException;
import com.gamma.nplus1.common.utils.IdGen;

/**
 * ClassName:AvoidDuplicateSubmissionInterceptor <br/>
 * Function: 防止重复提交过滤器. <br/>
 * Date: 2016年2月29日 下午5:17:33 <br/>
 * 
 * @author jeno
 * @version
 * @since JDK 1.6
 */
public class AvoidDuplicateSubmissionInterceptor implements HandlerInterceptor  {

	private Logger LOG = LoggerFactory.getLogger(getClass());

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		if (handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();

			AvoidDuplicateSubmission annotation = method.getAnnotation(AvoidDuplicateSubmission.class);
			if (annotation != null) {
				boolean needSaveSession = annotation.needSaveToken();
				if (needSaveSession) {
					request.getSession(false).setAttribute("token", IdGen.uuid());
				}

				boolean needRemoveSession = annotation.needRemoveToken();
				if (needRemoveSession) {
					if (isRepeatSubmit(request)) {
						LOG.warn("please don't repeat submit,[url:" + request.getServletPath() + "]");
						throw new InvalidTokenException();
					}
					request.getSession(false).removeAttribute("token");
				}
			}
			return true;
		} else {
			return true;
		}
	}

	private boolean isRepeatSubmit(HttpServletRequest request) {
		String serverToken = (String) request.getSession(false).getAttribute("token");
		if (serverToken == null) {
			return true;
		}
		String clinetToken = request.getParameter("token");
		if (clinetToken == null) {
			return true;
		}
		if (!serverToken.equals(clinetToken)) {
			return true;
		}
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}

}
